package com.example.springsecuritystudy.service.impl;

import com.example.springsecuritystudy.emuns.User;
import com.example.springsecuritystudy.mapper.UserMapper;
import com.example.springsecuritystudy.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import jakarta.annotation.Resource;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author LiuZiMing
 * @since 2024-01-05
 */
//注解用Component
@Component                                                                               //该接口定义类唯一的方法：登录
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService, UserDetailsService {

    @Resource
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println("UserServiceImpl.loadUserByUsername方法执行");
        MPJLambdaWrapper wrapper = new MPJLambdaWrapper<>();
        wrapper.eq("username", username);
        User user = userMapper.selectOne(wrapper);
        if (user == null) {
            //只有在抛出异常时才认定为登录失败
            throw new UsernameNotFoundException("用户不存在");
        } else {
            /*
             * 如果 loadUserByUsername未抛出异常，则校验返回值中保存的密码和请求参数密码是否匹配。
             * 获取spring容器中的PasswordEncoder类型对象，调用方法matches比较密码。
             * 如果密码比较结果是true，登录成功。
             * 如果密码比较结果是false，登录失败，重定向到/login?error。
             */
            org.springframework.security.core.userdetails.User result =
                    new org.springframework.security.core.userdetails.User(
                            username, //用户名
                            user.getPassword(), //登录用户的密码，是服务端保存到密文
                            AuthorityUtils.NO_AUTHORITIES //工具类 无权限集合
                    );
            return result;
        }

    }
}
